//
//  Common.h
//  ThreadCache
//
//  Created by 卜绎皓 on 2023/1/31.
//

#ifndef Common_h
#define Common_h


#endif /* Common_h */

#include <iostream>
#include <vector>
#include <assert.h>
#include <thread>
#include <time.h>

//小于等于MAX_BYTES，就找thread cache申请
//大于MAX_BYTES，就直接找page cache或者系统堆申请
static const size_t MAX_BYTES = 256 * 1024;
//thread cache和central cache自由链表哈希桶的表大小
static const size_t NFREELISTS = 208;



static void*& NextObj(void* obj)
{
    return *(void**)obj;
}

class FreeList
{
public:
    
    //将释放的头对象头插进自由链表
    void Push(void* obj)
    {
        assert(obj);
        //头插
        NextObj(obj) = _freeList;
        _freeList = obj;
    }
    
    
    //从自由链表头部获取对象
    void* Pop()
    {
        assert(_freeList);
        
        //头删
        void* obj = _freeList;
        _freeList = NextObj(_freeList);
        
        return obj;
    }
    
    bool Empty()
    {
        return _freeList == nullptr;
    }
private:
    void* _freeList = nullptr;//自由链表
};

//管理对齐和映射等关系
class SizeClass
{
public:
    
    static inline size_t _RoundUp(size_t bytes,size_t alignNum)
    {
//        //一般写法
//        size_t alignSize = 0;
//        if(bytes % alignNum != 0)
//        {
//            alignSize = (bytes / alignNum + 1)*alignNum;
//        }
//        else
//        {
//            alignSize = bytes;
//        }
//        return alignSize;
        
        //位运算写法
        return ((bytes + alignNum - 1)&~(alignNum-1));
    }
    
    //获取向上对齐后的字节数
    static inline size_t RoundUp(size_t bytes)
    {
        if(bytes <= 128)
        {
            return _RoundUp(bytes, 8);
        }
        
        else if(bytes <= 1024)
        {
            return _RoundUp(bytes, 16);
        }
        
        else if(bytes <= 8*1024)
        {
            return _RoundUp(bytes, 128);
        }
        
        else if(bytes <= 64*1024)
        {
            return _RoundUp(bytes, 1024);
        }
        
        else if(bytes <= 256*1024)
        {
            return _RoundUp(bytes, 8*1024);
        }
        
        else{
            assert(false);
            return -1;
        }
    }
    
    
    
    //获取对应哈希桶的下标
    static inline size_t _Index(size_t bytes,size_t alignNum)
    {
//        //一般写法
//        size_t index = 0;
//        if(bytes % alignNum != 0)
//        {
//            index = bytes / alignNum;
//        }
//        else
//        {
//            index = bytes / alignNum - 1;
//        }
//        return index;
        
        
        
        //位运算写法
        return ((bytes + (1 << alignNum) - 1) >> alignNum) - 1;
    }
    
    //获取对应哈希桶的下标
    static inline size_t Index(size_t bytes)
    {
        assert(bytes <= MAX_BYTES);
        
        //每个区间有多少个自由链表
        static size_t grounpArray[4] = {16,56,56,56};
        
        if(bytes <= 128)
        {
            return _Index(bytes, 3);
        }
        
        else if(bytes <= 1024)
        {
            return _Index(bytes - 128, 4) + grounpArray[0];
        }
        
        else if(bytes <= 8*1024)
        {
            return _Index(bytes - 128, 7) + grounpArray[0] + grounpArray[1];
        }
        
        else if(bytes <= 64*1024)
        {
            return _Index(bytes - 128, 10) + grounpArray[0] + grounpArray[1] + grounpArray[2];
        }
        
        else if(bytes <= 256*1024)
        {
            return _Index(bytes - 128, 13) + grounpArray[0] + grounpArray[1] + grounpArray[2] + grounpArray[3];
        }
        
        else
        {
            assert(false);
            return  -1;
        }
    }
};
